﻿using System;
using System.Collections.Generic;
using System.Linq;
using DataBaseLayer.Abstractions.Interfaces.Services;
using DataBaseLayer.Dto;

namespace DataBaseLayer.Services
{
	public class GalleriesService : IGalleriesService
	{
		#region Constants

		private const string SLASH = @"/";
		private const string BACK_SLASH = @"\";

		#endregion

		#region Variables

		private readonly Peresvet _dataBase;

		#endregion

		#region Constructors

		public GalleriesService(Peresvet dataBase)
		{
			if (dataBase == null)
				throw new ArgumentNullException(string.Format("data base"));
			_dataBase = dataBase;
		}

		#endregion

		#region IGalleriesService Members

		public int GetCountGalleries()
		{
			return _dataBase.Galleries.Count();
		}

		public IEnumerable<GalleryData> GetLastGalleries(int countFirstSkipGalleries)
		{
			return _dataBase.Galleries.OrderByDescending(n => n.Date).Skip(countFirstSkipGalleries - 1)
				.Select(g => new GalleryData
				{
					GalleryId = g.GalleryId,
					ImageUrl = g.Images.Any()
						? (g.Images.FirstOrDefault(i => i.IsDefault) ?? g.Images.FirstOrDefault()).Url
						: string.Empty,
					ThumbImageUrl = g.Images.Any()
						? (g.Images.FirstOrDefault(i => i.IsDefault) ?? g.Images.FirstOrDefault()).UrlThumb
						: string.Empty,
					Name = g.Name,
					Date = g.Date
				})
				.ToList();
		}

		public IEnumerable<GalleryData> GetGalleries()
		{
			return _dataBase.Galleries
				.Select(g => new GalleryData
				{
					GalleryId = g.GalleryId,
					ImageUrl = g.Images.Any()
						? (g.Images.FirstOrDefault(i => i.IsDefault) ?? g.Images.FirstOrDefault()).Url
						: string.Empty,
					ThumbImageUrl = g.Images.Any()
						? (g.Images.FirstOrDefault(i => i.IsDefault) ?? g.Images.FirstOrDefault()).UrlThumb
						: string.Empty,
					Name = g.Name,
					Date = g.Date
				})
				.OrderByDescending(n => n.Date)
				.ToList();
		}

		public void SaveGallery(GalleryData entity)
		{
			if (entity == null) return;

			var gallery = entity.GalleryId > 0
				? _dataBase.Galleries.SingleOrDefault(n => n.GalleryId == entity.GalleryId)
				: new Gallery();
			if (gallery == null) return;

			gallery.Name = entity.Name;
			gallery.Date = entity.Date;

			if (gallery.GalleryId == 0)
				_dataBase.Galleries.Add(gallery);
			_dataBase.SaveChanges();
		}

		public void DeleteGallery(int id)
		{
			var gallery = _dataBase.Galleries.SingleOrDefault(n => n.GalleryId == id);
			if (gallery != null)
			{
				_dataBase.Galleries.Remove(gallery);
				_dataBase.SaveChanges();
			}
		}

		public GalleryData GetGallery(int id)
		{
			return _dataBase.Galleries
				.Select(g => new GalleryData
				{
					ImageUrl = g.Images.Any()
						? (g.Images.FirstOrDefault(i => i.IsDefault) ?? g.Images.FirstOrDefault()).Url
						: string.Empty,
					ThumbImageUrl = g.Images.Any()
						? (g.Images.FirstOrDefault(i => i.IsDefault) ?? g.Images.FirstOrDefault()).UrlThumb
						: string.Empty,
					Date = g.Date,
					GalleryId = g.GalleryId,
					Name = g.Name,
					Images = g.Images
						.Where(i => !i.IsDefault)
						.Select(i => new ImageData
						{
							GalleryId = i.ImageId,
							ImageId = i.ImageId,
							IsDefault = i.IsDefault,
							Url = i.Url,
							UrlThumb = i.UrlThumb
						})
				})
				.SingleOrDefault(n => n.GalleryId == id);
		}

		public IEnumerable<ImageData> GetGalleryImagesByGalleryId(int id)
		{
			return _dataBase.Images
				.Where(i => i.Gallery != null && i.Gallery.GalleryId == id)
				.OrderBy(i => i.ImageId)
				.Select(i => new ImageData
				{
					GalleryId = i.ImageId,
					ImageId = i.ImageId,
					IsDefault = i.IsDefault,
					Url = i.Url,
					UrlThumb = i.UrlThumb
				}).ToList();
		}

		public void UpdateGalleryDefaultImage(int newDefaultImageId, bool isDefaultImage)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == newDefaultImageId);
			if (image == null) return;
			
			var images = _dataBase.Images.Where(i => i.GalleryId == image.GalleryId).OrderBy(i => i.ImageId).ToList();
			images.ForEach(i => i.IsDefault = false);
			image.IsDefault = isDefaultImage;
			if (!isDefaultImage)
			{
				var defImage = images.FirstOrDefault();
				if (defImage != null)
					defImage.IsDefault = true;
			}
			_dataBase.SaveChanges();
		}

		public string GetBigImageNameById(int id)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == id);
			var result = string.Empty;
			if (image != null && !string.IsNullOrWhiteSpace(image.Url))
			{
				var num = image.Url.LastIndexOf(SLASH, StringComparison.Ordinal);
				if (num == -1)
					num = image.Url.LastIndexOf(BACK_SLASH, StringComparison.Ordinal);
				if (num != -1)
					result = image.Url.Substring(num + 1);
			}
			return result;
		}

		public string GetSmallImageNameById(int id)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == id);
			var result = string.Empty;
			if (image != null && !string.IsNullOrWhiteSpace(image.UrlThumb))
			{
				var num = image.UrlThumb.LastIndexOf(SLASH, StringComparison.Ordinal);
				if (num == -1)
					num = image.UrlThumb.LastIndexOf(BACK_SLASH, StringComparison.Ordinal);
				if (num != -1)
					result = image.UrlThumb.Substring(num + 1);
			}
			return result;
		}

		public void DeleteImage(int id)
		{
			var image = _dataBase.Images.SingleOrDefault(i => i.ImageId == id);
			if (image == null) return;

			_dataBase.Images.Remove(image);
			if (image.IsDefault)
			{
				var images = _dataBase.Images.Where(i => i.GalleryId == image.GalleryId && i.ImageId != image.ImageId).OrderBy(i => i.ImageId).ToList();
				images.ForEach(i => i.IsDefault = false);
				var defImage = images.FirstOrDefault();
				if (defImage != null)
					defImage.IsDefault = true;
			}
			_dataBase.SaveChanges();
		}

		public int GetLastImageNumber()
		{
			var lastImage = _dataBase.Images.OrderByDescending(i => i.ImageId).FirstOrDefault();
			return lastImage != null ? lastImage.ImageId : 1;
		}

		public void CreateImage(ImageData image)
		{
			if (image == null) return;

			var newImage = new Image
			{
				GalleryId = image.GalleryId,
				Url = image.Url,
				UrlThumb = image.UrlThumb,
				IsDefault = !_dataBase.Images.Any(i => i.GalleryId == image.GalleryId)
			};
			_dataBase.Images.Add(newImage);
			_dataBase.SaveChanges();
		}

		#endregion
	}
}
